#include "PluginManager.h"
using namespace PlugManager;

int PluginManager::dspCounter = 0;

PluginManager::PluginManager(FMOD::System *system,FMOD::ChannelGroup* OutputChannel)
{
	FMOD::DSP *chorus;
	FMOD::DSP *compressor;
	FMOD::DSP *delay;
	FMOD::DSP *distortion;
	FMOD::DSP *flang;
	FMOD::DSP *echo;
	FMOD::DSP *highpass;
	FMOD::DSP *lowpass;
	FMOD::DSP *parameq;

	this->OutputChannel=OutputChannel;

	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_CHORUS, &chorus));
	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_COMPRESSOR, &compressor));
	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_DELAY, &delay));
	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_DISTORTION, &distortion));
	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_FLANGE, &flang));
	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_ECHO, &echo));
	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_HIGHPASS, &highpass));
	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &lowpass));
	AudioUtils::ERRCHECK(system->createDSPByType(FMOD_DSP_TYPE_PARAMEQ, &parameq));

	built_in_fx.push_back(chorus);
	built_in_fx.push_back(compressor);
	built_in_fx.push_back(delay);
	built_in_fx.push_back(echo);
	built_in_fx.push_back(distortion);
	built_in_fx.push_back(flang);
	built_in_fx.push_back(highpass);
	built_in_fx.push_back(lowpass);
	built_in_fx.push_back(parameq);

	byPassBuiltInFx(true);

	OutputChannel->addDSP(parameq,0);

	OutputChannel->addDSP(delay,0);
	OutputChannel->addDSP(echo,0);
	OutputChannel->addDSP(distortion,0);
	OutputChannel->addDSP(chorus,0);
	
	OutputChannel->addDSP(flang,0);
	
	OutputChannel->addDSP(highpass,0);
	OutputChannel->addDSP(lowpass,0);
	
	OutputChannel->addDSP(compressor,0);
	
}

PluginManager::PluginManager(const PluginManager & plugin){
	for(unsigned int i=0;i<plugin.built_in_fx.size();i++){
		built_in_fx.push_back(plugin.built_in_fx.at(i));
	}
	for(unsigned i=0;i<plugin.fxs->size();i++){
		FMOD::DSP fdsp= *plugin.fxs->at(i).dsp;
		PluginManager::addDSP(&fdsp);
	}
}
PluginManager & PluginManager::operator=(const PluginManager & plugin){
	for(unsigned i=0;i<plugin.built_in_fx.size();i++){
		built_in_fx.push_back(plugin.built_in_fx.at(i));
	}
	for(unsigned i=0;i<plugin.fxs->size();i++){
		FMOD::DSP fdsp= *plugin.fxs->at(i).dsp;
		PluginManager::addDSP(&fdsp);
	}
	return *this;
}

PluginManager::~PluginManager(void)
{
}
void PluginManager::addDSP(FMOD::DSP * dsp){
	Dsp my_dsp;
	my_dsp.dsp=dsp;
	my_dsp.ID=dspCounter;
	fxs->push_back(my_dsp);
	dspCounter++;
}
void PluginManager::rmDSP(int dspID){
	for(unsigned int i=0;i<fxs->size();i++)
	{
		if(fxs->at(i).ID==dspID)
		{
			fxs->erase(fxs->begin()+i);
		}
	}
}
void PluginManager::moveDSP(int dspBPos, int dspFPos){
	Dsp dsp = fxs->at(dspBPos);
	fxs->erase(fxs->begin()+dspBPos);
	fxs->insert(fxs->begin()+(dspFPos-1),dsp);
}
Dsp PluginManager::getDSP(int dspID){
	for(unsigned int i=0;i<fxs->size();i++)
	{
		if(fxs->at(i).ID==dspID)
		{
			return fxs->at(i);
		}
	}
	return fxs->at(0);
}
FMOD::DSP *PluginManager::getBuiltInDsp(FMOD_DSP_TYPE type){
	if(type == FMOD_DSP_TYPE_CHORUS)
		return built_in_fx.at(0);
	if(type == FMOD_DSP_TYPE_COMPRESSOR)
		return built_in_fx.at(1);
	if(type == FMOD_DSP_TYPE_DELAY)
		return built_in_fx.at(2);
	if(type == FMOD_DSP_TYPE_DISTORTION)
		return built_in_fx.at(3);
	if(type == FMOD_DSP_TYPE_ECHO)
		return built_in_fx.at(4);
	if(type == FMOD_DSP_TYPE_FLANGE)
		return built_in_fx.at(5);
	if(type == FMOD_DSP_TYPE_HIGHPASS)
		return built_in_fx.at(6);
	if(type == FMOD_DSP_TYPE_LOWPASS)
		return built_in_fx.at(7);
	if(type == FMOD_DSP_TYPE_PARAMEQ)
		return built_in_fx.at(8);
	return NULL;
}
dsp_list * PluginManager::getDSPs(){
	return fxs;
}
void PluginManager::byPassBuiltInFx(bool b){
	for(unsigned int i=0;i<built_in_fx.size();i++){
		built_in_fx.at(i)->setBypass(b);
	}
}